// Copyright 2011, Vanya Davidenko.
// Кодировка файла: UTF-8. 
package info.iu9.red;



class ReverseStringIterator extends StringIterator {
  ReverseStringIterator(final String string, final int begin, final int end) {
    reset(string, begin, end);
  }

  protected boolean checkBounds(final String string,
                                final int begin, final int end) {
    return -1 <= end && end <= begin && begin < string.length();
  }

  protected void concreteReset() {
    if ( Character.isHighSurrogate(string().charAt(begin())) ) {
      set_index(begin() + 2);
    } else {
      set_index(begin() + 1);
    }
    set_current_char_length(0);
  }

  public int next() {
    final char l;
    try {
     l = string().charAt(index() - 1);
    } catch(StringIndexOutOfBoundsException e) {
      assert index() == 0;
      set_current_char_length(1);
      set_index(-1);
      return EOL;
    }

    final int character;
    if ( Character.isLowSurrogate(l) ) {
      character = Character.toCodePoint(string().charAt(index() - 2), l);
      set_current_char_length(2);
      set_index(index() - 2);
    } else {
      character = l;
      set_current_char_length(1);
      set_index(index() - 1);
    }

    if ( index() == end() ) {
      return EOL;
    }
    return character;
  }

  public boolean isStringBegin() {
    return prevIndex() == string().length();
  }
  public boolean isStringEnd() {
    return index() == -1;
  }
  protected boolean nextIsStringEnd() {
    return index() == 0;
  }

  // Возврат отрицательного индекса не является ошибкой, хотя и запрещен JDK.
  // Такой индекс удобно использовать как маркер конца строки и по нему не будут
  // производиться обращения (в противном случае charAt сгенерирует исключение).
  protected int prevIndex() {
    return index() + current_char_length();
  }
  protected int nextIndex() {
    if ( index() == 0 ) {
      return -1;
    }
    if ( Character.isLowSurrogate(string().charAt(index() - 1)) ) {
      return index() - 2;
    }
    return index() - 1;
  }
}
